import 'dart:async';

import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/services.dart';

class GKBSignalR {
  final MethodChannel _channel = const MethodChannel('gkb_signalr');

  final String url;
  final String token;
  final Function(String)? receiveMessage;
  final Function(bool)? connectState;

  GKBSignalR({
    required this.url,
    required this.token,
    this.receiveMessage,
    this.connectState,
  }) {
    _signalRCallbackHandler();
  }

  void connect() async {
    try {
      _channel.invokeMethod<bool>("connectToServer", <String, dynamic>{
        'url': url,
        'token': token,
      });
    } on PlatformException catch (ex) {
      return Future.error(ex.message ?? '');
    } on Exception catch (ex) {
      return Future.error(ex.toString());
    }
  }

  void reconnect() async {
    try {
      await _channel.invokeMethod("reconnect");
    } on PlatformException catch (ex) {
      return Future.error(ex.message ?? '');
    } on Exception catch (ex) {
      return Future.error(ex.toString());
    }
  }

  void ackMessage({required List<int> ids}) async {
    try {
      await _channel.invokeMethod("ackMessage", <String, dynamic>{
        'ids': ids,
      });
    } on PlatformException catch (ex) {
      return Future.error(ex.message ?? '');
    } on Exception catch (ex) {
      return Future.error(ex.toString());
    }
  }

  void stop() async {
    try {
      await _channel.invokeMethod("stop");
    } on PlatformException catch (ex) {
      return Future.error(ex.message ?? '');
    } on Exception catch (ex) {
      return Future.error(ex.toString());
    }
  }

  void _signalRCallbackHandler() {
    _channel.setMethodCallHandler((call) {
      if (kDebugMode) {
        print('回传数据${call.arguments}');
      }
      switch (call.method) {
        case 'ReceiveMessage':
          receiveMessage?.call(call.arguments);
          break;
        case 'ConnectionStatus':
          connectState?.call(call.arguments);
          break;
        default:
      }
      return Future.value();
    });
  }
}
